<?php
namespace app\api\model;

use app\common\helper\ArrayHelper;
use app\common\helper\Obj2Array;
use app\common\model\project_model\ArticleModel as Article;
use app\api\model\BasicConfigModel;
use app\common\model\project_model\ArticleRecordModel;
use think\Db;
use think\Exception;

class ArticleModel extends Article {

    const INDEX_PAGE_NUM = 10; // 首页每页条数
    const RECOMMEND_PAGE_NUM = 5; // 推介的条数

    public static $error_msg = '';

    /**
     * list
     * @param $page
     * @param int $page_num
     * @return array|false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getList($page, $page_num = self::INDEX_PAGE_NUM) {
        $articleM = new self();
        $article = $articleM
            ->field('id, title, cover_img_url, created_time, type')
            ->where(['status' => ArticleModel::STATUS_OK])
            //->order('sort ASC, id DESC')
            ->page($page, $page_num)
            ->select();
        if (!empty($article)) {
            $article = Obj2Array::resObject2Array($article);
            shuffle($article);
        }
        return $article;
    }

    /**
     * 美文详情
     *
     * @param $article_id
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function detail($article_id) {
        $articleM = new self();
        $article = $articleM->field(['token', 'cate_id', 'cate_name', 'updated_time', 'status', 'from_url', 'sort'], true)->where(['id' => $article_id])->find();
        $data = $article;
        if (!empty($data['content'])) {
            $data['content'] = self::formatContent($data['content']);
        }
        $data['created_time'] = date('Y-m-d', strtotime($data['created_time']));
        $data['share_img_url'] = $data['share_img_url']?$data['share_img_url']:$data['cover_img_url'];
        return $data;
    }

    /**
     * 格式化
     * @param $content
     * @return string
     */
    private static function formatContent($content) {
        return $content;
    }

    /**
     * 推介算法：
     * 此处先简单处理，以后首页及推荐美文再扩展
     * 精准推介
     *
     * 现在的处理：
     * 过滤掉已读和首页list的数据
     * @param $page
     * @param $page_index
     * @param $user
     * @return array|false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function recommend($page, $page_index, $user) {
        // 已读记录
        $articleRecordM = new ArticleRecordModel();
        $ARList = $articleRecordM->where(['wechat_id' => $user['id']])->distinct(true)->column('article_id');

        // 过滤掉已读和首页及已经加载的数据的推荐数据
        $article_start =  $page_index*self::INDEX_PAGE_NUM + $page*self::RECOMMEND_PAGE_NUM;// 数据开始的索引用于limit
        $articleM = new self();
        $article = $articleM
            ->field('id, title, cover_img_url, created_time, type')
            ->where(['status' => ArticleModel::STATUS_OK])
            ->where('id', 'NOT IN', $ARList)
            ->order('sort ASC, id DESC')
            ->limit($article_start, self::RECOMMEND_PAGE_NUM)
            ->select();
        if (!empty($article)) {
            $article = Obj2Array::resObject2Array($article);
        } else { // 没有可以推荐的数据时，不加过滤直接返回
            $article = self::getList($page, self::RECOMMEND_PAGE_NUM);
        }
        return $article;
    }

    /**
     * 点击事件
     * @param $article_id
     * @param $user
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function click($article_id, $user) {

        $articleM = new self();
        if (!$res = ($articleM->where(['id' => $article_id])->setInc('real_click'))) {
            self::$error_msg = '更新美文失败';
            return false;
        }
        $article = $articleM->field(['id' => 'article_id', 'cate_name' => 'article_cate_name', 'title' => 'article_title'])->where(['id' => $article_id])->find();
        // 新增浏览记录
        $articleRecordM = new ArticleRecordModel();
        $data = [
            'wechat_id' => $user['id'],
            'open_id' => $user['openid'],
            'nick_name' => $user['nick_name'],
            'applet_app_id' => $user['applet_id'],
            'created_time' => date('Y-m-d H:i:s', time()),
        ];
        $data = array_merge($data, $article->getData());
        $res = $articleRecordM->allowField(true)->save($data);
        if (!$res) {
            self::$error_msg = '新增浏览记录失败';
            return false;
        }
        return true;
    }

    public function share($article_id) {
        return $this->where(['id' => $article_id])->setInc('real_share');
    }

    /**
     * 分享以后的推荐美文
     * @param $user
     * @return array|false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function afterShare($user) {
        // 已读记录
        $articleRecordM = new ArticleRecordModel();
        $ARList = $articleRecordM->where(['wechat_id' => $user['id']])->distinct(true)->column('article_id');
        $articleM = new self();
        $article = $articleM
            ->field('id, title, cover_img_url, created_time, type')
            ->where(['status' => ArticleModel::STATUS_OK])
            ->where('id', 'NOT IN', $ARList)
            ->select();
        $count = count($article);
        if (!empty($article)) {
            $article = Obj2Array::resObject2Array($article);
        }
        if ($count>=5) {// 数据够时
            return ArrayHelper::get_rand_array($article, 5);
        } else { // 未读的数据不够时，不加过滤直接随机返回
            if (!$res = self::randRecord(5-$count)) {
                return false;
            }
            if (!empty($article)) {
                $article = array_merge($article, $res);
            }
        }
        return $article;
    }

    /**
     * 随机从0-100的记录中取指定条数的数据
     * @param int $num 取数据条数
     * @return array|bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private static function randRecord($num) {
        $articleM = new self();
        $article = $articleM
            ->field('id, title, cover_img_url, created_time, type')
            ->where(['status' => ArticleModel::STATUS_OK])
            ->limit(0, 100)
            ->select();
        $count = count($article);
        if (empty($article) || $count < $num) {
            self::$error_msg = '缺少数据';
            return false;
        }
        $article = Obj2Array::resObject2Array($article);
        return ArrayHelper::get_rand_array($article, $num);
    }
}